package com.zhu.classfile.constant.base;

import com.zhu.classfile.constant.ConstantInfo;
import com.zhu.classfile.constant.ConstantPool;
import com.zhu.classfile.constant.ConstantTag;

import java.nio.ByteBuffer;

/**
 * CONSTANT_Methodref_info 结构
 * 用于表示对类方法的符号引用
 * 结构：{ tag (1), class_index (2), name_and_type_index (2) }
 * 第一,除了表示本类中被其它本类方法调用的方法外,还表示本类方法中调用其它类的方法
 */
public class ConstantMethodrefInfo implements ConstantInfo {

    private final ConstantTag tag = ConstantTag.CONSTANT_Methodref;

    // 指向常量池中 CONSTANT_Class_info 的索引
    private int classIndex;

    // 指向常量池中 CONSTANT_NameAndType_info 的索引
    private int nameAndTypeIndex;

    private final ConstantPool cp;

    public ConstantMethodrefInfo(ConstantPool cp) {
        this.cp = cp;
    }

    @Override
    public void readInfo(ByteBuffer reader) {
        this.classIndex = Short.toUnsignedInt(reader.getShort());
        this.nameAndTypeIndex = Short.toUnsignedInt(reader.getShort());
    }

    public int getClassIndex() {
        return classIndex;
    }

    public int getNameAndTypeIndex() {
        return nameAndTypeIndex;
    }

    @Override
    public ConstantTag getTag() {
        return tag;
    }

    public String getClassName() {
        ConstantClassInfo classInfo = (ConstantClassInfo) cp.get(classIndex);
        return classInfo.getClassName();
    }

    public String getName() {
        ConstantNameAndTypeInfo nameAndTypeInfo = (ConstantNameAndTypeInfo) cp.get(nameAndTypeIndex);
        return nameAndTypeInfo.getName();
    }

    public String getType() {
        ConstantNameAndTypeInfo nameAndTypeInfo = (ConstantNameAndTypeInfo) cp.get(nameAndTypeIndex);
        return nameAndTypeInfo.getDescriptor();
    }

    @Override
    public String toString() {
        return String.format("CONSTANT_Methodref_info{class_index=%d, name_and_type_index=%d}",
                classIndex, nameAndTypeIndex);
    }
}
